/**
 * 
 */
package br.embedded.ufcg.rmi;

import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.UnknownHostException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.util.List;

import org.jgrapht.Graph;
import org.jgrapht.graph.DefaultEdge;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver;

import br.edu.ufcg.embedded.mysocial.GraphCacheManager;
import br.edu.ufcg.embedded.util.Compressor;
import br.embedded.socialapp.business.Usuario;

/**
 * @author daniel
 *
 */
public class Client
{
	private static int NUMBERT_OF_THREADS;
	private static int MAX_RECORDS;
	private static int MAX_LEVELS;
	private static String SERVER_URL;

	private static Graph<Usuario, DefaultEdge> graph;
	private static List<Usuario> jobList;
	
	private static String hostname;

	public static void main(String[] args)
	{
		if (args != null && args.length == 4)
		{
			try
			{
				SERVER_URL = args[0];
				NUMBERT_OF_THREADS = Integer.parseInt(args[1]);
				MAX_RECORDS = Integer.parseInt(args[2]);
				MAX_LEVELS = Integer.parseInt(args[3]);
			}
			catch (Exception e) {
				e.printStackTrace();
			}
			
			hostname = getIp();
			
			register();
			read();
			getJobList();
			
			GraphCacheManager manager = new GraphCacheManager(graph, jobList, MAX_LEVELS,1, MAX_RECORDS);
			
			Long t1 = System.currentTimeMillis();
			manager.run();
			Long t2 = System.currentTimeMillis();
			
			setTime(t2 - t1);
		}
		else
		{
			System.out.println("ClientProcess: Invalid parameters input.");
		}
		
	}

	private static void read()
	{
		Process process;

		try {
			process = (Process) Naming.lookup(SERVER_URL);
			byte[] compressedGraph = process.getGraph();

			Compressor compressor = new Compressor();

			XStream xStream = new XStream(new JettisonMappedXmlDriver());
			graph = (Graph<Usuario, DefaultEdge>) xStream.fromXML(compressor.decompress(compressedGraph));

			System.out.println("ClientProcess: a Graph with " + graph.vertexSet().size() + " nodes was received sucessfully.");
		}
		catch(MalformedURLException e )
		{
			System.out.println();
			System.out.println("MalformedURLException: " + e.toString());
		}  
		catch(RemoteException e )
		{ 
			System.out.println();
			System.out.println("RemoteException: " + e.toString());
		}  
		catch(NotBoundException e )
		{
			System.out.println();
			System.out.println("NotBoundException: " + e.toString()); 
		}
	}

	private static void register()
	{
		Process process;
		
		try {
			process = (Process) Naming.lookup(SERVER_URL);
			process.register(hostname);
		} catch(MalformedURLException e )
		{
			System.out.println();
			System.out.println("MalformedURLException: " + e.toString());
		}  
		catch(RemoteException e )
		{ 
			System.out.println();
			System.out.println("RemoteException: " + e.toString());
		}  
		catch(NotBoundException e )
		{
			System.out.println();
			System.out.println("NotBoundException: " + e.toString()); 
		}
	}
	
	private static void setTime(long time)
	{
		Process process;
		
		try {
			process = (Process) Naming.lookup(SERVER_URL);
			process.setEndTime(hostname, time);
		} catch(MalformedURLException e )
		{
			System.out.println();
			System.out.println("MalformedURLException: " + e.toString());
		}  
		catch(RemoteException e )
		{ 
			System.out.println();
			System.out.println("RemoteException: " + e.toString());
		}  
		catch(NotBoundException e )
		{
			System.out.println();
			System.out.println("NotBoundException: " + e.toString()); 
		}
	}
	
	private static void getJobList()
	{
		Process process;
		
		try {
			process = (Process) Naming.lookup(SERVER_URL);
			
			byte[] compressedJob = process.getJobList(hostname);

			Compressor compressor = new Compressor();

			XStream xStream = new XStream(new JettisonMappedXmlDriver());
			jobList = (List<Usuario>) xStream.fromXML(compressor.decompress(compressedJob));
			
			System.out.println("Tamanho da lista de trabalho: " + jobList.size());
			
		} catch(MalformedURLException e )
		{
			System.out.println();
			System.out.println("MalformedURLException: " + e.toString());
		}  
		catch(RemoteException e )
		{ 
			System.out.println();
			System.out.println("RemoteException: " + e.toString());
		}
		catch(NotBoundException e )
		{
			System.out.println();
			System.out.println("NotBoundException: " + e.toString()); 
		}
	}

	private static String getIp()
	{
		try {
			return InetAddress.getLocalHost().getHostAddress();
		} catch (UnknownHostException e) {
			return new String("127.0.0.1");
		}  
	}  
}